﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Backend.Packets
{
    public class ChatPacket : IPacket
    {
        public enum ChatCommand : short
        {
            MESSAGE_ROOM,
            MESSAGE_FROM_ROOM,
            MESSAGE_USER,
            MESSAGE_FROM_USER,
            JOIN_ROOM,
            JOIN_ROOM_RESPONSE,
            LEAVE_ROOM,
            LIST_ROOM,
            LIST_ROOM_RESPONSE,
            LIST_ROOMS,
            LIST_ROOMS_REPONSE
        }

        public enum ChatResponse : short
        {
            ACCEPTED,
            DENIED
        }

        private string m_sFrom;
        private string m_sTo;
        private string m_sRoom;
        private string m_sMessage;
        private bool m_bPrivate;
        private ChatCommand m_Command;
        private byte[] m_Data;
        private short m_nLength;
        private const short PacketId = 0;

        /// <summary>
        /// Room Private Status.
        /// </summary>
        public bool Private
        {
            get
            {
                return m_bPrivate;
            }
            set
            {
                m_bPrivate = value;
            }
        }

        public string Room
        {
            get
            {
                return m_sRoom;
            }
            set
            {
                m_sRoom = value;
            }
        }

        public string From
        {
            get
            {
                return m_sFrom;
            }
            set
            {
                m_sFrom = value;
            }
        }

        public string To
        {
            get
            {
                return m_sTo;
            }
            set
            {
                m_sTo = value;
            }
        }

        public string Message
        {
            get
            {
                return m_sMessage;
            }
            set
            {
                m_sMessage = value;
            }
        }

        public ChatCommand Command
        {
            get
            {
                return m_Command;
            }
            set
            {
                m_Command = value;
            }
        }

        public ChatPacket()
        {
        }

        public byte[] Pack()
        {
            switch (Command)
            {
                case ChatCommand.JOIN_ROOM:
                    Data = Encoding.ASCII.GetBytes(Room);
                    break;
                case ChatCommand.JOIN_ROOM_RESPONSE:
                    Data = Encoding.ASCII.GetBytes(Message);
                    break;
                case ChatCommand.LIST_ROOM:
                    Data = Encoding.ASCII.GetBytes(Room);
                    break;
                case ChatCommand.LIST_ROOM_RESPONSE:
                    Data = Encoding.ASCII.GetBytes(Message);
                    break;
                case ChatCommand.MESSAGE_FROM_ROOM:
                    Data = Encoding.ASCII.GetBytes(From + "," + Message);
                    break;
                case ChatCommand.MESSAGE_FROM_USER:
                    Data = Encoding.ASCII.GetBytes(From + "," + Message);
                    break;
                case ChatCommand.MESSAGE_ROOM:
                    Data = Encoding.ASCII.GetBytes(Room + "," + Message);
                    break;
                case ChatCommand.MESSAGE_USER:
                    Data = Encoding.ASCII.GetBytes(To + "," + Message);
                    break;
                case ChatCommand.LIST_ROOMS:
                    Data = new byte[0];
                    break;
            }

            MemoryStream MemStream = new MemoryStream();
            BinaryWriter Writer = new BinaryWriter(MemStream);

            Length = (short)(10 + Data.Length);

            Writer.Write(Length);
            Writer.Write(PacketId);
            Writer.Write((short)Command);
            Writer.Write(Private);

            MemStream.Position += 3;

            Writer.Write(Data);

            MemStream.Capacity = Length;

            return MemStream.GetBuffer();
        }

        public void Load(byte[] Buffer)
        {
            MemoryStream MemStream = new MemoryStream(Buffer);
            BinaryReader Reader = new BinaryReader(MemStream);

            Length = Reader.ReadInt16();
            MemStream.Position += 2;
            Command = (ChatCommand)Reader.ReadInt16();
            Private = Reader.ReadBoolean();
            MemStream.Position += 3;

            Data = Reader.ReadBytes(Length - 10);

            string sTemp = Encoding.ASCII.GetString(Data); ;

            switch (Command)
            {
                case ChatCommand.LIST_ROOM:
                    Room = sTemp;
                    break;
                case ChatCommand.JOIN_ROOM:
                    Room = sTemp;
                    break;
                case ChatCommand.MESSAGE_ROOM:
                    {
                        string[] Tokens = sTemp.Split(',');

                        if (Tokens.Length != 2)
                            return;

                        Room = Tokens[0];
                        Message = Tokens[1];
                        break;
                    }
                case ChatCommand.JOIN_ROOM_RESPONSE:
                    Message = sTemp;
                    break;
                case ChatCommand.LIST_ROOM_RESPONSE:
                    Message = sTemp;
                    break;
                case ChatCommand.MESSAGE_FROM_ROOM:
                    {
                        string[] Tokens = sTemp.Split(',');

                        if (Tokens.Length != 2)
                            return;

                        From = Tokens[0];
                        Message = Tokens[1];

                        break;
                    }
                case ChatCommand.MESSAGE_FROM_USER:
                    {
                        string[] Tokens = sTemp.Split(',');

                        if(Tokens.Length != 2)
                            return;
                        From = Tokens[0];
                        Message = Tokens[1];
                        break;
                    }
                case ChatCommand.MESSAGE_USER:
                    {
                        string[] Tokens = sTemp.Split(',');

                        if (Tokens.Length != 2)
                            return;
                        To = Tokens[0];
                        Message = Tokens[1];

                        break;
                    }
                case ChatCommand.LIST_ROOMS_REPONSE:
                    Message = Encoding.ASCII.GetString(Data);
                    break;
            }
        }

        public byte[] Data
        {
            get
            {
                return m_Data;
            }
            set
            {
                m_Data = value;
            }
        }

        public short Length
        {
            get
            {
                return m_nLength;
            }
            set
            {
                m_nLength = value;
            }
        }
    }
}
